package pay.config;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.StringUtils;

@Configuration
public class RedisConfig {

    @Value("${spring.redis.host:localhost}")
    private String host;

    @Value("${spring.redis.port:6379}")
    private int port;

    @Value("${spring.redis.password:}")
    private String password;

    @Value("${spring.redis.database:0}")
    private int database;

    /**
     * 创建 RedissonClient Bean - 专门用于分布式锁
     */
    @Bean(destroyMethod = "shutdown")
    public RedissonClient redissonClient() {
        try {
            Config config = new Config();
            config.useSingleServer()
                    .setAddress("redis://" + host + ":" + port)
                    .setDatabase(database) // 使用配置的数据库
                    .setConnectionPoolSize(64)
                    .setConnectionMinimumIdleSize(10)
                    .setIdleConnectionTimeout(10000)
                    .setConnectTimeout(5000)
                    .setTimeout(3000)
                    .setRetryAttempts(3)
                    .setRetryInterval(1500);

            // 只有在密码不为空时才设置密码
            if (StringUtils.hasText(password)) {
                config.useSingleServer().setPassword(password);
            }

            return Redisson.create(config);
        } catch (Exception e) {
            throw new RuntimeException("Failed to create RedissonClient: " + e.getMessage(), e);
        }
    }

    // 以下是你原有的 Redis 连接配置，保持不变
    /**
     * 连接0号库：用户token相关
     */
    @Bean(name = "redisConnectionFactory0")
    public RedisConnectionFactory redisConnectionFactory0() {
        return createConnectionFactory(0);
    }

    /**
     * 连接1号库：业务数据相关
     */
    @Bean(name = "redisConnectionFactory1")
    public RedisConnectionFactory redisConnectionFactory1() {
        return createConnectionFactory(1);
    }

    /**
     * 连接2号库：小程序用户token相关
     */
    @Bean(name = "redisConnectionFactory2")
    public RedisConnectionFactory redisConnectionFactory2() {
        return createConnectionFactory(2);
    }

    /**
     * 连接3号库：小程序业务数据相关
     */
    @Bean(name = "redisConnectionFactory3")
    @Primary
    public RedisConnectionFactory redisConnectionFactory3() {
        return createConnectionFactory(3);
    }

    private LettuceConnectionFactory createConnectionFactory(int dbIndex) {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        config.setHostName(host);
        config.setPort(port);
        config.setPassword(RedisPassword.of(password));
        config.setDatabase(dbIndex);
        return new LettuceConnectionFactory(config);
    }

    // ... 你原有的其他 RedisTemplate Bean 配置保持不变
    @Bean
    @Primary
    public RedisTemplate<String, Object> redisTemplate() {
        return createRedisTemplate(redisConnectionFactory0());
    }

    @Bean(name = "appTokenRedisTemplate")
    public RedisTemplate<String, Object> appTokenRedisTemplate(
            @Qualifier("redisConnectionFactory0") RedisConnectionFactory factory) {
        return createRedisTemplate(factory);
    }

    @Bean(name = "appBizRedisTemplate")
    public RedisTemplate<String, Object> appBizRedisTemplate(
            @Qualifier("redisConnectionFactory1") RedisConnectionFactory factory) {
        return createRedisTemplate(factory);
    }

    @Bean(name = "tokenRedisTemplate")
    public RedisTemplate<String, Object> tokenRedisTemplate(
            @Qualifier("redisConnectionFactory2") RedisConnectionFactory factory) {
        return createRedisTemplate(factory);
    }

    @Bean(name = "bizRedisTemplate")
    public RedisTemplate<String, Object> bizRedisTemplate(
            @Qualifier("redisConnectionFactory3") RedisConnectionFactory factory) {
        return createRedisTemplate(factory);
    }

    @Bean(name = "bizStringRedisTemplate")
    public StringRedisTemplate bizStringRedisTemplate(
            @Qualifier("redisConnectionFactory3") RedisConnectionFactory factory) {
        return new StringRedisTemplate(factory);
    }

    private RedisTemplate<String, Object> createRedisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }
}